home *** CD-ROM | disk | FTP | other *** search
- /*
- * WireDevice.C - wire frame device driver.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include "WireDevice.h"
- #include "Polygon.h"
- #include "Sphere.h"
-
- static const int defaultConeResolution = 3;
- static const int defaultSphereResolution = 4;
-
- //___________________________________________________________ WireDevice
-
- WireDevice::WireDevice(BaseWindow* window, Options* options)
- : DeviceDriver(options), w(window), polys(NULL)
- {
- coneResolution = (theOptions->coneResolution <= 0)
- ? defaultConeResolution
- : theOptions->coneResolution;
- sphereResolution = (theOptions->sphereResolution <= 0)
- ? defaultSphereResolution
- : theOptions->sphereResolution;
-
- /*
- * Make up table for cone generation.
- */
- sintable = new real[coneResolution];
- costable = new real[coneResolution];
-
- for (register int i=0; i<coneResolution; i++) {
- real alpha = (2*M_PI*i)/coneResolution;
-
- sintable[i] = sin(alpha);
- costable[i] = cos(alpha);
- }
- top = new Vector[coneResolution];
- bottom = new Vector[coneResolution];
-
- /*
- * Generate unit sphere.
- */
- unitSphere = Sphere::tesselation(Vector(0,0,0), 1, sphereResolution);
- }
-
- WireDevice::~WireDevice()
- {
- delete [] sintable;
- delete [] costable;
- delete [] top;
- delete [] bottom;
- delete w;
-
- for (register long i=0; i<unitSphere->count(); i++)
- delete unitSphere->item(i);
- delete unitSphere;
-
- StringTable_Iterator macroItr(macroNames);
- while(macroItr.more()){
- PolygonList* polys = (PolygonList*)macroItr.cur_value();
- for (i = 0; i<polys->count(); i++)
- delete polys->item(i);
- delete polys;
- macroItr.next();
- }
- }
-
- void WireDevice::begin()
- {
- if (!theOptions->autoscale) {
- w->disableBuffering();
- w->setView(theOptions->eye, theOptions->lookat, theOptions->up,
- theOptions->fov);
- }
- w->open(theOptions->resX, theOptions->resY, "L-System " + LSystemName);
- if (theOptions->autoscale)
- w->writeText("Please wait ...",
- theOptions->resX/2-40, theOptions->resY/2-5);
- }
-
- void WireDevice::end(const BoundingBox& b)
- {
- char key;
-
- if (theOptions->verbose)
- cerr << "primitives: "<< primitives << '\n';
- if (theOptions->autoscale) {
- w->setView(b, theOptions->up, theOptions->fov);
- w->clear();
- }
- w->flush();
- do {
- key = w->waitForKey();
- } while(key != 'q' && key != 'Q');
- w->close();
- }
-
- void WireDevice::cylinder(const Vector& p1, const Vector& p2, real r)
- {
- cone(p1, r, p2, r);
- }
-
- void WireDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
- {
- Vector axis = p2-p1;
-
- /*
- * Degenerated cone?
- */
- if (axis.normalize() == 0)
- return;
-
- Vector u, v;
-
- /*
- * Calculate 2 vectors normal to cone axis and to each other.
- */
- u[0] = -axis[1]; u[1] = axis[0]; u[2] = 0;
- if (u.normalize() == 0) {
- u[0] = axis[2]; u[1] = 0; u[2] = -axis[0];
- u.normalize();
- }
- v = axis*u;
-
- Vector d;
- for (register int i=0; i<coneResolution; i++) {
- d = costable[i]*u + sintable[i]*v;
- *(bottom+i) = p1 + d*r1;
- *(top+i) = p2 + d*r2;
- }
-
- for (i=0; i<coneResolution; i++) {
- Polygon* p = new Polygon(*(bottom+i), *(top+i),
- *(top+((i+1)%coneResolution)),
- *(bottom+((i+1)%coneResolution)));
- if (definingMacro)
- polys->append(p);
- else {
- primitives++;
- w->polygon(p);
- }
- }
- }
-
- void WireDevice::polygon(Polygon* p)
- {
- if (definingMacro)
- polys->append(p);
- else {
- primitives++;
- w->polygon(p);
- }
- }
-
- void WireDevice::sphere(const Vector& pos, real r)
- {
- /*
- * Transform the unit sphere to radius r and position pos.
- */
- for (register long i=0; i<unitSphere->count(); i++) {
- Polygon* p = unitSphere->item(i);
- Polygon* transformedPoly = new Polygon(p->numVertices());
- for (register long j=0; j<p->numVertices(); j++)
- transformedPoly->addVertex(p->vertex(j)*r+pos);
-
- if (definingMacro)
- polys->append(transformedPoly);
- else {
- primitives++;
- w->polygon(transformedPoly);
- }
- }
- }
-
- void WireDevice::beginMacro(const rcString& macroName)
- {
- definingMacro = 1;
- currentMacroName = macroName;
- polys = new PolygonList(100);
- }
-
- void WireDevice::endMacro()
- {
- definingMacro = 0;
- macroNames.find_and_replace(currentMacroName, polys);
- polys = NULL;
- }
-
- void WireDevice::executeMacro(const rcString& macroName,
- const TransMatrix& tmat)
- {
- anyPtr argument;
- if (!macroNames.lookup(macroName, argument))
- Error(ERR_PANIC, "WireDevice::executeMacro: macro "
- + macroName + " does not exist");
-
- PolygonList* polyList = (PolygonList*) argument;
- for (register long i=0; i<polyList->count(); i++) {
- Polygon* p = new Polygon(*polyList->item(i));
- p->transform(tmat);
-
- if (definingMacro)
- polys->append(p);
- else {
- primitives++;
- w->polygon(p);
- }
- }
- }
-